package com.navinfo.tripanalysis.pojo;

import org.apache.spark.sql.Row;
import org.apache.spark.sql.catalyst.expressions.GenericRow;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 位置点公共信息
 * @author machi
 * @create 2018/05/15
 **/
public interface Point extends Serializable {
    /**
     * 0f37
     */
    byte PROTOCOL_0F37 = 1;
    /**
     * 0200
     */
    byte PROTOCOL_0200 = 2;

    /**
     * 车辆tid(公共)
     * @return
     */
    long getTid();

    /**
     * 行程id(公共)
     * @return
     */
    int getTripId();

    /**
     * 获取协议类型(公共)
     *
     * @return
     */
    byte getProtocol();

    /**
     * gps时间，单位毫秒 （公共）
     */
    long getGpsTime();

    /**
     * 速度,单位km/h (公共)
     */
    double getSpeedKmh();

    /**
     * 纬度 ，单位：以度为单位乘以10的6次方(公共)
     */
    int getLatitude();

    /**
     * 经度 ，单位：以度为单位乘以10的6次方(公共)
     */
    int getLongitude();

    /**
     * 方向0-359正北为0顺时针(公共)
     */
    int getDirection();

    /**
     * 高程，海拔高度，单位为米（m）（有符号数）单位米 (公共)
     */
    double getHeight();

    /**
     * 发动机输出扭矩，单位：%(公共)
     */
    int getEngineOutputTorque();

    /**
     * 转速，单位：rpm（转每分钟）(公共)
     */
    int getRotation();

    /**
     * 油门，单位：%(公共)
     */
    int getAccPedalPos();

    /**
     * 离合器开关(公共)
     */
    int getClutchSwitch();

    /**
     * 发动机瞬时油耗，单位：km/L(公共)
     */
    double getRealTimeOilConsumption();

    /**
     * 发动机燃油消耗率,单位：L/h(公共)
     */
    double getFuelConsumptionRate();
    /**
     * 燃油总消耗，单位：L(公共)
     */
    double getTotalFuelCons();
    /**
     * 获取流水号(0200特有，0f37为0)
     * @return
     */
    int getSerialNumber();
    /**
     * 获取尿素喷射值(0f37特有，0200为0)
     * @return
     */
    int getUreaInjection();

    /**
     * 尿素液位(0f37特有，0200为0)
     * @return
     */
    int getUreaLevel();
    /**
     * 仪表车速(0f37特有，0200为0)
     * @return
     */
    double getInstrumentSpeed();


    Comparator<Point> COMPARATOR = (o1, o2) -> {
        int r = 0;
        if (o1 != null && o2 != null) {
            //根据gpsTime排序
            if (o1.getGpsTime() > o2.getGpsTime()) {
                r = 1;
            } else if (o1.getGpsTime() < o2.getGpsTime()) {
                r = -1;
            }else{
                //根据协议排序，将0200放天0f37前面
                int t1 = Point.PROTOCOL_0200 == (o1.getProtocol()) ? 0 : 1;
                int t2 = Point.PROTOCOL_0200 == (o2.getProtocol()) ? 0 : 1;
                r = t1 - t2;

                //最后根据流水号排序(相同协议)  r==0 <=> t1==t2
                if (r == 0) {
                    int serial1 = o1.getSerialNumber();
                    int serial2 = o2.getSerialNumber();
                    if (serial1 > serial2) {
                        r = 1;
                    } else if (serial1 < serial2) {
                        r = -1;
                    }else{
                        //最后按转速排序，0f37流水号都为0
                        r = o1.getRotation() - o2.getRotation();
                    }
                }
            }
        }
        return r;
    };

    /**
     * 创建公共协议的Row值
     * @return
     */
    default Row createRow() {
        List<String> list = new ArrayList<>();

        if(this instanceof Point0200){
            Point0200 point = (Point0200) this;
            list.add(String.valueOf(point.getTid()));
            list.add(String.valueOf(point.getTripId()));
            list.add("0200");
            list.add(String.valueOf(point.getGpsTime()));
            list.add(String.valueOf(point.getSpeedKmh()*100));
            list.add(point.getLatitude()+"");
            list.add(point.getLongitude()+"");
            list.add(point.getDirection()+"");
            list.add(point.getHeight()+"");
            list.add(point.getEngineOutputTorque()*100+"");
            list.add(point.getRotation()*100+"");
            list.add(point.getAccPedalPos()*100+"");
            list.add(null);//0200没有制动信号
            list.add(point.getClutchSwitch()*100+"");
            list.add(point.getRealTimeOilConsumption()*100+"");
            list.add(point.getFuelConsumptionRate()*100+"");
            list.add(null);//0200没有大气温度
            //0200特有
            list.add(point.getAccStatus()+"");
            list.add(point.getGpsMileage()*1000+"");
            list.add(point.getEcuMileage()*100+"");
            list.add(point.getMeterMileage()*100+"");
            list.add(point.getIntegralMileage()*100+"");
            list.add(point.getStandardMileage()+"");
            list.add(point.getIntegralFuelCons()*100+"");
            list.add(point.getTotalFuelCons()*100+"");
            list.add(point.getStandardFuelCons()+"");
            list.add(point.getCoolingWaterTem()*100+"");
            list.add(point.getIntakeAirTem()*100+"");
            list.add(point.getIntakePressure()*100+"");
            list.add(point.isCruiseControl()==true ? "1" : "0");
            list.add(point.getOilPercentage()*100+"");
            list.add(point.getHandBrakeStatus()+"");
            list.add(point.getSlideNeutralStatus()+"");
            list.add(point.getRapidAccelerationStatus()+"");
            list.add(point.getRapidDecelerationStatus()+"");
            list.add(point.getSharpTurningStatus()+"");
            list.add(point.getSlamAcceleratorStatus()+"");
            list.add(point.getAmtLoad()+"");
            list.add(point.getVecuLoad()+"");
            list.add(point.isPatch()==true ? "1" : "0");
            list.add(point.getSerialNumber()+"");
            list.add(String.valueOf(point.getInstrumentSpeed()*100));
            list.add(point.getUreaInjection()+"");
            list.add(point.getUreaLevel()+"");
        }else if(this instanceof Point0F37){
            Point0F37 point = (Point0F37) this;
            list.add(String.valueOf(point.getTid()));
            list.add(String.valueOf(point.getTripId()));
            list.add("0f37");
            list.add(String.valueOf(point.getGpsTime()));
            list.add(String.valueOf(point.getSpeedKmh()*100));
            list.add(point.getLatitude()+"");
            list.add(point.getLongitude()+"");
            list.add(point.getDirection()*100+"");
            list.add(point.getHeight()+"");
            list.add(point.getEngineOutputTorque()*100+"");
            list.add(point.getRotation()*100+"");
            list.add(point.getAccPedalPos()*100+"");
            list.add(point.getBrake()*100+"");
            list.add(point.getClutchSwitch()*100+"");
            list.add(point.getRealTimeOilConsumption()*100+"");
            list.add(point.getFuelConsumptionRate()*100+"");
            list.add(point.getAtmosphericTem()*100+"");
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(null);
            list.add(point.getSerialNumber()+"");
            list.add(String.valueOf(point.getInstrumentSpeed()*100));
            list.add(point.getUreaInjection()+"");
            list.add(point.getUreaLevel()+"");
        }

        return new GenericRow(list.toArray());
    }

}
